<template>
  <div class="column-menu-container">
    <a-dropdown :trigger="['click']">
      <slot></slot>
      <a-menu
        v-if="menuMode === 'single'"
        slot="overlay"
        :selected-keys="selectedKeys"
        @click="onClick"
      >
        <a-sub-menu v-if="isShowFilterClean" title="筛选器">
          <a-menu-item
            v-if="isEnabled(StatisticsAction.filterSelected)"
            @click="
              $emit(
                'open-config-panel',
                'panel',
                StatisticsAction.filterSelected
              )
            "
            >特定值</a-menu-item
          >
          <a-menu-item
            v-if="isEnabled(StatisticsAction.filterNumberRange)"
            v-show="['int', 'decimal'].includes(column.desc)"
            @click="
              $emit(
                'open-config-panel',
                'panel',
                StatisticsAction.filterNumberRange
              )
            "
            >值范围</a-menu-item
          >
          <a-menu-item
            v-if="isEnabled(StatisticsAction.filterDateRange)"
            v-show="column.desc === 'date'"
            @click="
              $emit(
                'open-config-panel',
                'panel',
                StatisticsAction.filterDateRange
              )
            "
            >日期范围</a-menu-item
          >
          <a-menu-item
            v-if="isEnabled(StatisticsAction.filterWildcard)"
            v-show="['varchar', 'text'].includes(column.desc)"
            @click="
              $emit(
                'open-config-panel',
                'panel',
                StatisticsAction.filterWildcard
              )
            "
            >通配符匹配</a-menu-item
          >
          <a-menu-item
            v-if="isEnabled(StatisticsAction.filterNull)"
            @click="
              $emit('open-config-panel', 'panel', StatisticsAction.filterNull)
            "
            >Null值</a-menu-item
          >
        </a-sub-menu>
        <a-sub-menu
          v-if="['varchar', 'text'].includes(column.desc) && isShowStringClean"
          title="清理"
        >
          <a-menu-item :key="StatisticsAction.upperCase">设为大写</a-menu-item>
          <a-menu-item :key="StatisticsAction.lowerCase">设为小写</a-menu-item>
          <a-menu-item :key="StatisticsAction.removeLetter"
            >移除字母</a-menu-item
          >
          <a-menu-item :key="StatisticsAction.removeNumber"
            >移除数字</a-menu-item
          >
          <a-menu-item :key="StatisticsAction.removePunctuation"
            >移除标点符号</a-menu-item
          >
          <a-menu-divider />
          <a-menu-item :key="StatisticsAction.trimSpace">剪裁空格</a-menu-item>
          <a-menu-item :key="StatisticsAction.removeAllSpace"
            >移除所有空格</a-menu-item
          >
          <a-menu-item :key="StatisticsAction.removeRepeatCells"
            >移除重复行</a-menu-item
          >
        </a-sub-menu>
        <a-sub-menu
          v-if="
            ['decimal', 'int', 'varchar', 'text'].includes(column.desc) &&
            isShowStringClean
          "
          title="异常值处理"
        >
          <a-menu-item
            @click="
              $emit(
                'open-config-panel',
                'panel',
                StatisticsAction.handleSpecificOutliers
              )
            "
            >特定值</a-menu-item
          >
          <a-menu-item
            v-if="['varchar', 'text'].includes(column.desc)"
            @click="
              $emit(
                'open-config-panel',
                'panel',
                StatisticsAction.handleWildcardOutliers
              )
            "
            >通用符匹配</a-menu-item
          >
          <a-menu-item
            @click="
              $emit(
                'open-config-panel',
                'panel',
                StatisticsAction.handleNullOutliers
              )
            "
            >Null值</a-menu-item
          >
        </a-sub-menu>
        <a-sub-menu
          v-if="
            isEnabled(StatisticsAction.aggreFunc) &&
            ['decimal', 'int', 'varchar', 'text'].includes(column.desc)
          "
          title="聚合函数"
        >
          <a-menu-item
            v-if="['decimal', 'int'].includes(column.desc)"
            @click="
              $emit(
                'open-config-panel',
                'panel',
                StatisticsAction.aggreFunc,
                'avg'
              )
            "
            >均值</a-menu-item
          >
          <a-menu-item
            v-if="['decimal', 'int'].includes(column.desc)"
            @click="
              $emit(
                'open-config-panel',
                'panel',
                StatisticsAction.aggreFunc,
                'sum'
              )
            "
            >求和</a-menu-item
          >
          <a-menu-item
            v-if="['decimal', 'int'].includes(column.desc)"
            @click="
              $emit(
                'open-config-panel',
                'panel',
                StatisticsAction.aggreFunc,
                'max'
              )
            "
            >最大值</a-menu-item
          >
          <a-menu-item
            v-if="['decimal', 'int'].includes(column.desc)"
            @click="
              $emit(
                'open-config-panel',
                'panel',
                StatisticsAction.aggreFunc,
                'min'
              )
            "
            >最小值</a-menu-item
          >
          <a-menu-item
            @click="
              $emit(
                'open-config-panel',
                'panel',
                StatisticsAction.aggreFunc,
                'count'
              )
            "
            >计数</a-menu-item
          >
        </a-sub-menu>
        <a-sub-menu
          v-if="
            isEnabled(StatisticsAction.splitColumn) &&
            ['varchar', 'text'].includes(column.desc)
          "
          title="拆分值"
        >
          <a-menu-item
            @click="
              $emit('open-config-panel', 'dialog', StatisticsAction.splitColumn)
            "
            >自定义拆分</a-menu-item
          >
        </a-sub-menu>
        <a-menu-item
          v-if="isEnabled(StatisticsAction.createColumn)"
          @click="$emit('create-new-column')"
          >按示例新增列</a-menu-item
        >
        <a-menu-item
          v-if="isEnabled(StatisticsAction.formulaColumn)"
          @click="$emit('formula-new-column')"
          >按公式新增列
        </a-menu-item>
        <a-menu-item
          v-if="isEnabled(StatisticsAction.partitionBy)"
          @click="$emit('partition-by')"
          >分组排序新增列
        </a-menu-item>
        <!-- 对象解析 -->
        <a-menu-item
          v-if="isEnabled(StatisticsAction.jsonParse) && isJsonCol"
          @click="
            $emit('open-config-panel', 'panel', StatisticsAction.jsonParse)
          "
          >对象解析</a-menu-item
        >
        <!-- 数组解析 -->
        <a-menu-item
          v-if="isEnabled(StatisticsAction.arrayParse) && isArrayCol"
          @click="
            $emit('open-config-panel', 'panel', StatisticsAction.arrayParse)
          "
          >数组解析</a-menu-item
        >

        <a-menu-divider v-show="isShowToggleStatMode" />
        <a-menu-item-group v-show="isShowToggleStatMode" title="查看状态">
          <a-menu-item key="detail">详细信息</a-menu-item>
          <a-menu-item key="binned">摘要</a-menu-item>
        </a-menu-item-group>
        <a-menu-divider
          v-if="isEnabled(['rename-column', 'copy-column', 'keep-only-column'])"
        />
        <a-menu-item
          v-if="isEnabled(StatisticsAction.editOrder) && isOrderSemantic"
          :key="StatisticsAction.editOrder"
          >编辑有序顺序</a-menu-item
        >
        <a-menu-item
          v-if="isEnabled(StatisticsAction.renameColumn)"
          :key="StatisticsAction.renameColumn"
          >重命名字段</a-menu-item
        >
        <a-menu-item
          v-if="isEnabled(StatisticsAction.copyColumn)"
          :key="StatisticsAction.copyColumn"
          >复制字段</a-menu-item
        >
        <a-menu-item
          v-if="isEnabled(StatisticsAction.keepOnlyColumn)"
          :key="StatisticsAction.keepOnlyColumn"
          >仅保留字段</a-menu-item
        >
        <a-menu-divider v-if="isEnabled(StatisticsAction.deleteColumn)" />
        <a-menu-item
          v-if="isEnabled(StatisticsAction.deleteColumn)"
          :key="StatisticsAction.deleteColumn"
          >移除</a-menu-item
        >

        <slot name="menu"></slot>
      </a-menu>
      <a-menu v-else slot="overlay" @click="onClick">
        <a-menu-item :key="StatisticsAction.chimeraIntoJson"
          >嵌合成对象</a-menu-item
        >
        <a-menu-item :key="StatisticsAction.chimeraIntoArray"
          >嵌合成数组</a-menu-item
        >
        <a-menu-item :key="StatisticsAction.mergeColumn">合并</a-menu-item>
        <a-menu-item :key="StatisticsAction.keepOnlyColumn">仅保留</a-menu-item>
        <a-menu-item :key="StatisticsAction.deleteColumn">移除</a-menu-item>
      </a-menu>
    </a-dropdown>
  </div>
</template>

<script lang="ts">
import { IColumn, OptionPreViewAction } from '@/store/modules/dataview'
import { Vue, Component, Prop } from 'vue-property-decorator'
import { StatisticsAction } from '@/util/data-selection-actions'

@Component({
  components: {},
})
export default class ColumnMenu extends Vue {
  @Prop() private column!: IColumn
  @Prop() private statMode!: string
  @Prop({ default: [] }) tools!: string[] // 启用的菜单功能列表，为null关闭全部功能，空数组启用全部功能
  @Prop() selectedColumns!: IColumn[]

  private StatisticsAction = StatisticsAction
  private OptionPreViewAction = OptionPreViewAction

  private get isShowToggleStatMode() {
    // 2021.08.21 时间不能概览, columnMenu 不能切换查看状态
    return ['int', 'decimal'].includes(this.column.desc!)
  }

  // 该字段为对象 menu 对象解析选项的显示与否
  public get isJsonCol() {
    return this.column.desc === 'json'
  }
  // 该字段为数组 menu 数组解析选项的显示与否
  public get isArrayCol() {
    return this.column.desc === 'array'
  }
  // 该列语义为 有序
  public get isOrderSemantic() {
    return this.column.semantic === 'order'
  }

  private get selectedKeys() {
    return this.isShowToggleStatMode
      ? this.statMode === 'detail'
        ? ['detail']
        : ['binned']
      : []
  }

  private get menuMode(): 'single' | 'multiple' {
    // 菜单展示类型，分为单个字段或多个字段
    if (this.selectedColumns.length > 1) {
      const index = this.selectedColumns.findIndex(
        (c) => c.name === this.column.name
      )
      return index === -1 ? 'single' : 'multiple'
    }
    return 'single'
  }

  /**
   * 是否展示菜单中字符串清理功能
   */
  private get isShowStringClean() {
    return this.isEnabled([
      StatisticsAction.upperCase,
      StatisticsAction.lowerCase,
      StatisticsAction.removeLetter,
      StatisticsAction.removeNumber,
      StatisticsAction.removePunctuation,
      StatisticsAction.trimSpace,
      StatisticsAction.removeAllSpace,
      StatisticsAction.removeRepeatCells,
    ])
  }

  private get isShowFilterClean() {
    return this.isEnabled([
      StatisticsAction.filterSelected,
      StatisticsAction.filterNumberRange,
      StatisticsAction.filterDateRange,
      StatisticsAction.filterWildcard,
      StatisticsAction.filterNull,
    ])
  }

  private isEnabled(key: string | string[]) {
    if (!this.tools || !Array.isArray(this.tools)) {
      return false
    }
    if (this.tools.length === 0) {
      return true
    }
    if (Array.isArray(key)) {
      return key.some((item) => this.tools.includes(item))
    }
    return this.tools.includes(key)
  }

  private onClick({ key }: any) {
    if (
      [
        StatisticsAction.renameColumn,
        StatisticsAction.copyColumn,
        StatisticsAction.keepOnlyColumn,
        StatisticsAction.deleteColumn,
        StatisticsAction.trimSpace,
        'detail',
        'binned',
        StatisticsAction.upperCase,
        StatisticsAction.lowerCase,
        StatisticsAction.removeLetter,
        StatisticsAction.removeNumber,
        StatisticsAction.removePunctuation,
        StatisticsAction.removeAllSpace,
        StatisticsAction.removeRepeatCells,
        StatisticsAction.mergeColumn,
        StatisticsAction.chimeraIntoJson, // 嵌合成对象
        StatisticsAction.chimeraIntoArray, // 嵌合成数组
        StatisticsAction.editOrder, // 编辑有序顺序
      ].includes(key)
    ) {
      this.$emit('menu-item-clicked', key)
    } else {
      this.$emit('customize-menu-click', key)
    }
  }
}
</script>

<style lang="less" scoped>
.column-menu-container {
  display: inline;
}
</style>
